# -*- coding: utf-8 -*-
"""
This implements the Main Window.
"""
import os
import curve

from PyQt4 import QtGui
from PyQt4 import QtCore
from glwidget import GlWidget
from glwidget import Painter
from glwidget import PainterCurve
from glwidget import PainterPoints


class MainWindow (QtGui.QMainWindow):
    """
        TODO
    """
    
    def __init__(self, parent=None):
        """
            Constructor
        """
        super(MainWindow, self).__init__(parent)
        self.setObjectName("MainWindow")
        self.resize(1020, 815)
        self.setWindowTitle(QtGui.QApplication.translate( "MainWindow",
                  "Manipulação Direta", None, QtGui.QApplication.UnicodeUTF8 ) ) 
 
        self.centralwidget = QtGui.QWidget(self)
        self.setCentralWidget(self.centralwidget)


        self.widget = QtGui.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(0, 0, 1015, 815))
        self.vboxlayout = QtGui.QVBoxLayout(self.widget)
                
        self.glwidget = GlWidget(self.widget)
        self.glwidget.setGeometry(QtCore.QRect(2, 2, 782, 642))
        self.glwidget.painter = Painter()

        self.browser = QtGui.QTextBrowser(self.widget)
        self.browser.setGeometry(QtCore.QRect(790, 2, 230, 400))


        self.curve_widget = QtGui.QWidget(self.widget)
        self.curve_widget.setGeometry(QtCore.QRect(790, 405, 300, 75))
        
        self.curve_label = QtGui.QLabel("CURVE",self.curve_widget)
        self.curve_label.setGeometry(QtCore.QRect(70, 0, 110, 15))

        self.radio_buttom_opened = QtGui.QRadioButton(self.curve_widget)
        self.radio_buttom_opened.setGeometry(QtCore.QRect(0, 20, 110, 15))
        self.radio_buttom_opened.setText("Curve Opened")
        self.radio_buttom_opened.setChecked(True)
        self.connect(self.radio_buttom_opened, QtCore.SIGNAL("clicked()"), self.setOpened)

        self.radio_buttom_closed = QtGui.QRadioButton(self.curve_widget)
        self.radio_buttom_closed.setGeometry(QtCore.QRect(110, 20, 100, 15))
        self.radio_buttom_closed.setText("Curve Closed")
        self.connect(self.radio_buttom_closed, QtCore.SIGNAL("clicked()"), self.setClosed)

        self.curveColorButton = QtGui.QPushButton(self.curve_widget)
        self.curveColorButton.setGeometry(QtCore.QRect(0, 40, 80, 25))
        self.curveColorButton.setText("&Curve Color")
        self.connect(self.curveColorButton, QtCore.SIGNAL("clicked()"), self.getCurveColor)
         
        self.curveColorLabel = QtGui.QLabel(self.curve_widget)
        self.curveColorLabel.setGeometry(QtCore.QRect(110, 40, 80, 25))
        self.curveColorLabel.setFrameShape(QtGui.QFrame.StyledPanel)
        self.curveColorLabel.setScaledContents(True)
        self.curveColor = QtGui.QColor(QtCore.Qt.white)
        self.setColor(self.curveColor, self.curveColorLabel)

        self.points_widget = QtGui.QWidget(self.widget)
        self.points_widget.setGeometry(QtCore.QRect(790, 480, 300, 100))

        self.points_label = QtGui.QLabel("CONTROL POINTS",self.points_widget)
        self.points_label.setGeometry(QtCore.QRect(50, 0, 110, 15))

        self.check_box_points_enabled = QtGui.QCheckBox(self.points_widget)
        self.check_box_points_enabled.setGeometry(QtCore.QRect(0, 20, 180, 15))
        self.check_box_points_enabled.setText("Control Points Enabled")
        self.check_box_points_enabled.setChecked(True)
        self.connect( self.check_box_points_enabled, QtCore.SIGNAL("clicked()"), 
                                                     self.setShowPointsEnabled )

        self.pointsColorButton = QtGui.QPushButton(self.points_widget)
        self.pointsColorButton.setGeometry(QtCore.QRect(0, 40, 80, 25))
        self.pointsColorButton.setText("&Points Color")
 
        self.pointsColorLabel = QtGui.QLabel(self.points_widget)
        self.pointsColorLabel.setGeometry(QtCore.QRect(110, 40, 80, 25))
        self.pointsColorLabel.setFrameShape(QtGui.QFrame.StyledPanel)
        self.pointsColorLabel.setScaledContents(True)
        self.connect( self.pointsColorButton, QtCore.SIGNAL("clicked()"), 
                                              self.getColorPoints )
        self.color_points = QtGui.QColor(QtCore.Qt.white)
        self.setColor(self.color_points, self.pointsColorLabel)

        self.pointsSizeLabel = QtGui.QLabel("Points size",self.points_widget)
        self.pointsSizeLabel.setGeometry(QtCore.QRect(10, 70, 65, 25))

        self.pointSizeSpinBox = QtGui.QSpinBox(self.points_widget)
        self.pointSizeSpinBox.setGeometry(QtCore.QRect(80, 70, 80, 25))
        self.pointSizeSpinBox.setRange(1, 10)
        self.pointSizeSpinBox.setValue(5)
        self.pointSizeSpinBox.setToolTip("Size of the Points")
        self.pointSizeSpinBox.setStatusTip(self.pointSizeSpinBox.toolTip())
        self.pointSizeSpinBox.setFocusPolicy(QtCore.Qt.NoFocus)


        self.buttom = QtGui.QPushButton("Generate Curve", self.widget)
        self.buttom.setGeometry(QtCore.QRect(855, 580, 100, 30))
        self.connect(self.buttom, QtCore.SIGNAL("clicked()"), self.newCurve)       

        self.manipulation_curve_enabled = QtGui.QCheckBox(self.widget)
        self.manipulation_curve_enabled.setGeometry( 
                                               QtCore.QRect(790, 620, 180, 15) )
        self.manipulation_curve_enabled.setText("Manipulation Curve Enabled")
        self.manipulation_curve_enabled.setChecked(True)
        self.manipulation_curve_enabled.setEnabled(False)
        self.connect( self.manipulation_curve_enabled, 
               QtCore.SIGNAL("clicked()"), self.setManipulationCurveEnabled )



        self.menubar = QtGui.QMenuBar(self)
        self.menubar.setGeometry( QtCore.QRect(0, 0, 468, 25) )

        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenu.setTitle( QtGui.QApplication.translate( "MainWindow",
                                "&File", None, QtGui.QApplication.UnicodeUTF8) )

        self.actionNew = QtGui.QAction(self)
        self.fileMenu.addAction(self.actionNew)
        self.actionNew.setText(QtGui.QApplication.translate( "MainWindow",
                                "&New", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionNew, QtCore.SIGNAL("activated()"), self.newFile)
                                
        self.actionOpen = QtGui.QAction(self)
        self.fileMenu.addAction(self.actionOpen)
        self.actionOpen.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Open", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionOpen, QtCore.SIGNAL("activated()"), self.openFile)
        
        self.actionSave = QtGui.QAction(self)
        self.fileMenu.addAction(self.actionSave)
        self.actionSave.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Save", None, QtGui.QApplication.UnicodeUTF8) )
        self.connect(self.actionSave, QtCore.SIGNAL("activated()"), self.saveFile)        
        
        self.actionQuit = QtGui.QAction(self)
        self.actionQuit.setObjectName("actionQuit")
        self.fileMenu.addAction(self.actionQuit)
        self.actionQuit.setText(QtGui.QApplication.translate( "MainWindow",
                                "&Quit", None, QtGui.QApplication.UnicodeUTF8) )


        self.statusbar = QtGui.QStatusBar(self)
        self.setStatusBar(self.statusbar)

        QtCore.QMetaObject.connectSlotsByName(self)
        
        self.filename = None

    def on_actionQuit_triggered(self):
        """
            This metod is called when the action actionQuit is triggered, 
            ie when the Quit menu entry is triggered.

            The control of the called is doing by QT.
        """
        exit()

    def newFile(self):
        """
            This metod is called when the action actionNew activated.
            
            This create a new file with data of a curve.
        """
        # Limpa o widget
        self.glwidget.painter = PainterPoints ( Painter() )
        self.glwidget.glDraw() 
        
        # Habilita a criação de novas curvas
        self.glwidget.creating = True
        
        # Apaga os antigos pontos de controle do widget
        self.glwidget.control_point_list = []
        
        self.manipulation_curve_enabled.setEnabled(False)
        
    def newCurve(self):
        """
            This metod is called when the buttom Generate Curve (self.buttom) 
            is clicked.
            
            This show a curve on widgwet.
        """
        # The curve is don't drawed if there are less than three points 
        if len(self.glwidget.control_point_list) > 3:
            control_point_list = self.glwidget.control_point_list
            
            self.glwidget.painter = PainterCurve( self.glwidget.painter )
            
            factory = curve.BSplineFactory()
            self.glwidget.painter.curve = factory.createBSplineCurve("CURVE", 
                                                  control_point_list, "Global" )
       
            self.glwidget.painter.setColor( float( self.curveColor.red() ) / 255,
                                            float( self.curveColor.green() ) / 255, 
                                            float( self.curveColor.blue() ) / 255,
                                            "Curve" )
            # Draw the curve and the control points
            self.glwidget.glDraw()
            self.glwidget.creating = False
            self.manipulation_curve_enabled.setEnabled(True)
                                    

    def openFile(self):
        """
            This metod is called when the action actionOpen activated.
            
            This open a file with data of a curve.
        """
        dir = os.path.dirname(self.filename) if self.filename is not None else "."

        # Lista de formatos de Imagens suportados
        formats = ["*.txt", "*.inp"]
        
        # Seleciona um arquivo e configura a caixa de dialogo para abertura deste
        filename = unicode(QtGui.QFileDialog.getOpenFileName(self,
                            "Open File", dir,
                            "File types: %s" % " ".join(formats)))
        
        # Se um arquivo for selecionado chama o metodo para le-lo
        if filename:
            content = self.loadFile(filename)
    
        self.glwidget.painter = Painter()
        if self.check_box_points_enabled.isChecked():
            self.glwidget.painter = PainterPoints( self.glwidget.painter )
            self.glwidget.painter.drawer.point_list = content[5]
            self.glwidget.painter.setColor( float( self.color_points.red() ) / 255,
                                            float( self.color_points.green() ) / 255, 
                                            float( self.color_points.blue() ) / 255,
                                            "Points" )    
    
        self.glwidget.painter = PainterCurve( self.glwidget.painter )
        
        factory = curve.BSplineFactory()
        self.glwidget.painter.curve = factory.createBSplineCurve("CURVE", content[5], "Global" )
      
        self.glwidget.painter.setColor( float( self.curveColor.red() ) / 255,
                                        float( self.curveColor.green() ) / 255, 
                                        float( self.curveColor.blue() ) / 255,
                                        "Curve" )          
        self.glwidget.glDraw()
        self.manipulation_curve_enabled.setEnabled(True)        

    def loadFile(self, filename=None):
        # Não entendi
        if filename is None:
            action = self.sender()
            if isinstance(action, QAction):
                filename = unicode(action.data().toString())
            else:
                return
        
        if filename:
            self.filename = None
            source = open(filename, "r")
            self.browser.clear()
            
            self.browser.append("CURVE")
            curve_opened = source.readline().split("#")[0]
            self.browser.append("Opened:  %s"%curve_opened)
            line = source.readline().split("#")[0].split()
            curve_color = ( line[0], line[1], line[2] )
            self.browser.append("Colors (RGB):  ( %s,  %s,  %s )" % curve_color)

            self.browser.append("\nCONTROL POINTS")
            cp_enabled = source.readline().split("#")[0] 
            self.browser.append( "Enabled:  %s" % cp_enabled )      
            line = source.readline().split("#")[0].split()
            cp_color = ( line[0], line[1], line[2] )
            self.browser.append("Colors (RGB): ( %s,  %s,  %s )" % cp_color )
            cp_size = source.readline().split("#")[0]
            self.browser.append("Size:  %s"%cp_size)

            self.browser.append("List of Control Points:")
            line = source.readline() # just comment
            line = source.readline().split()
            cp_list = []
            while (line):
                point = [0.0, 0.0, 0.0]
                for i in range(3):
                    point[i] = float(line[i])
                cp_list.append(point)
                self.browser.append("( %s,   %s,   %s )" % 
                                     ( point[0], point[1], point[2] ))
                line = source.readline().split()
            source.close()
            
        return ( curve_opened, curve_color, 
                 cp_enabled, cp_color, cp_size, cp_list )
                 
    def saveFile(self):
        dirname = os.path.dirname(self.filename) if self.filename is not None else "."
        formats = ["*.txt", "*.inp"]
        filename = unicode(QtGui.QFileDialog.getSaveFileName(self,
                            "Save File", dirname,
                            "File types: %s" % " ".join(formats)))
        source = open(filename, "w")
        #TODO: Escrever o conteudo correto no arquivo
        source.write("%s # The Curve is oppened\n" % self.radio_buttom_opened.isChecked() )
        source.write("%s %s %s # Colors of curve (RGB between 0 and 1)\n" 
                                  % ( float(self.curveColor.red() ) / 255, 
                                    float( self.curveColor.green() ) / 255, 
                                    float( self.curveColor.blue() ) / 255) )
        source.write("%s # Enabled Control Points\n" % self.check_box_points_enabled.isChecked() )
        source.write("%s %s %s # Colors of points (RGB between 0 and 1)\n" 
                                  % ( float(self.color_points.red() ) / 255, 
                                    float( self.color_points.green() ) / 255, 
                                    float( self.color_points.blue() ) / 255) )
        source.write("%s # Size of Control Points\n" % self.pointSizeSpinBox.value() )
        source.write("# List of Control Points:\n")
        for point in self.glwidget.control_point_list:
            source.write( "%s  %s  %s\n" % ( point[0], point[1], point[2] ) )

    def getCurveColor(self):
        color = QtGui.QColorDialog.getColor(QtCore.Qt.black, self)
        if color.isValid():
            self.curveColor = color
            self.setColor(self.curveColor, self.curveColorLabel)
            self.glwidget.painter.setColor( float( color.red() ) / 255,
                                            float( color.green() ) / 255, 
                                            float( color.blue() ) / 255,
                                            "Curve" )
        self.glwidget.glDraw()

    def getColorPoints(self):
        color = QtGui.QColorDialog.getColor(QtCore.Qt.black, self)
        if color.isValid():
            self.color_points = color
            self.setColor(self.color_points, self.pointsColorLabel)
            self.glwidget.painter.setColor( float( color.red() ) / 255,
                                            float( color.green() ) / 255, 
                                            float( color.blue() ) / 255,
                                            "Points" )
        self.glwidget.glDraw()

    def setColor(self, color, label):
        pixmap = self._makePixmap(color, 60, 30)
        label.setPixmap(pixmap) 
        
    def _makePixmap(self, color, width, height):
        pixmap = QtGui.QPixmap(width, height)
        brush = QtGui.QBrush(color, QtCore.Qt.BrushStyle(QtCore.Qt.SolidPattern))
        painter = QtGui.QPainter(pixmap)
        painter.fillRect(pixmap.rect(), brush)
        return pixmap                        
        
    def setOpened(self):
        self.glwidget.painter.opened = True
        self.glwidget.glDraw()

    def setClosed(self):
        self.glwidget.painter.opened = False   
        self.glwidget.glDraw()     
        
    def setShowPointsEnabled(self):
        self.glwidget.painter.points_enabled = self.check_box_points_enabled.isChecked() 
        self.glwidget.glDraw()  
        
    def setManipulationCurveEnabled(self):
        self.glwidget.painter.bbox_enabled = self.manipulation_curve_enabled.isChecked() 
        self.glwidget.glDraw()         
